#include "String.h"

/*
void* memset(void* s,int v,int n)
{
	register char* so = (char*)s;
	while(n--)
	*so++ = (char)v;
	return s;
}

void* memcpy(void* d,const void* s,int n)
{
	register char* x = (char*)d;
	register char* si= (char*)s;
	while(n--)
	*x++ = *si++;
	return d;
}

int Compare(const char* src, const char* dst)
{
	if (!src && !dst) return 0;
	if (!src || !dst) return -2;

	int ret = 0 ;
	while( ! (ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
		++src, ++dst;
	
	if ( ret < 0 )
		ret = -1 ;
	else if ( ret > 0 )
		ret = 1 ;
	
	return (ret);
}

int Compare(const wchar_t* src, const wchar_t* dst)
{
	if (!src && !dst) return 0;
	if (!src || !dst) return -2;

	int ret = 0 ;
	while( ! (ret = *(wchar_t*)src - *(wchar_t*)dst) && *dst)
		++src, ++dst;
	
	if ( ret < 0 )
		ret = -1 ;
	else if ( ret > 0 )
		ret = 1 ;
	
	return (ret);
}
*/

TStr CA2T(AStr s, int cp)
{
	if (s.ise()) return L"";
	int len = MultiByteToWideChar(cp, 0, *s, -1, NULL, 0)-1; 
	TStr r(len);
	MultiByteToWideChar(cp, 0, *s, -1, *r, len);
	r[len]='\0';
	r.length() = len;
	return r;
}

AStr CT2A(TStr s, int cp)
{
	if (s.ise()) return "";
	int len = WideCharToMultiByte(cp, 0, *s, -1, NULL, 0,NULL,NULL)-1; 
	AStr r(len);
	WideCharToMultiByte(cp, 0, *s, -1, *r, len,NULL,NULL);
	r[len]='\0';
	r.length() = len;
	return r;
}

AStr CA2U(AStr a)
{
	if (a.ise()) return "";
	AStr res;
	int l = MultiByteToWideChar(CP_ACP,0,*a,-1,NULL,0)-1;
	if (l!=-1)
	{
		TStr r(l);
		MultiByteToWideChar(CP_ACP,0,*a,-1,*r,l);
		r[l]=L'\0';
		r.length() = l;

		l = WideCharToMultiByte(CP_UTF8,0,*r,-1,NULL,0,NULL,NULL)-1;
		if (l!=-1)
		{
			res.buffer(l);
			WideCharToMultiByte(CP_UTF8, 0, *r, -1, *res, l,NULL,NULL);
			res[l]='\0';
			res.length() = l;
		}
	}

	return res;
}

AStr CU2A(AStr u)
{
	if (u.ise()) return "";
	AStr res;
	int l = MultiByteToWideChar(CP_UTF8,0,*u,-1,NULL,0)-1;
	if (l!=-1)
	{
		TStr r(l);
		MultiByteToWideChar(CP_UTF8,0,*u,-1,*r,l);
		r[l]=L'\0';
		r.length() = l;

		l = WideCharToMultiByte(CP_ACP,0,*r,-1,NULL,0,NULL,NULL)-1;
		if (l!=-1)
		{
			res.buffer(l);
			res[l]='\0';
			WideCharToMultiByte(CP_ACP, 0, *r, -1, *res, l,NULL,NULL);
			res.length() = l;
		}
	}

	return res;
}


AStr Hex2Bin(AStr H)
{
	AStr res;
	if (H.In("0-9a-fA-F"))
	{
		int i=0;
		long c;
		if (H.length() % 2==1)
		{
			c = (long)H.mid(0,1).htol();
			res=(char)c;
			i=1;
		}
		for(;i<H.length();i+=2)
		{
			c = (long)H.mid(i,2).htol();
			res += (char)c;
		}
	}
	return res;
}

AStr Bin2Hex(AStr B, bool uc)
{
	AStr res,hd = "0123456789abcdef";
	int i=0;
	if (uc) hd.toupper();
	char c;
	for(;i<B.length();i++)
	{
		c = B[i];
		res += hd[(c>>4) & 0xF];
		res += hd[c & 0xF];
	}
	return res;
}

AStr jPrintf(const char* f, ...)
{
	int l = strlen(f)+512;
	AStr res;
	
	va_list ap;
	va_start(ap,f);
	
	while(1){
		res.buffer(l);
		res.length() = _vsnprintf( *res, res.alength(), f, ap );
		if (res.length()!=-1) break;
		l+=l;
	}
	va_end(ap);
	return res;
	
}

template<class T>
String<T> jPrintf(const T* f, ...)
{
	int l = strlen(f)+512;
	AStr res;
	
	va_list ap;
	va_start(ap,f);
	
	while(1)
	{
		res.buffer(l);
		res.length() = _vsnprintf( *res, res.alength(), f, ap );
		if (res.length()!=-1) break;
		l+=l;
	}
	va_end(ap);
	return res;
	
}

TStr jPrintf(const TCHAR* f, ...)
{
	int l = wcslen(f)+512;
	TStr res;
	
	va_list ap;
	va_start(ap,f);
	
	while(1){
		res.buffer(l);
		res.length() = _vsnwprintf( *res, res.alength(), f, ap );
		if (res.length()!=-1) break;
		l+=l;
	}
	va_end(ap);
	return res;
	
}

AStr i2s(int i)
{
	return jPrintf("%d",i);
}

AStr Read(const char* f)
{
	AStr r;
	if (f)
	{
		FILE * fp = fopen(f,"rb");
		if (fp)
		{
			int l;
			char buf[1025];
			while(!feof(fp))
			{
				memset(buf,0,1025);
				l = fread(buf, sizeof(char), 1024, fp);
				buf[l]=0;
				r.assign(buf,l,true);
			}
			fclose(fp);
		}
	}
	return r;
}
	
bool Write(const char* f, AStr d)
{
	if (f)
	{
		FILE * fp = fopen(f,"wb");
		if (fp)
		{
			fwrite(*d,sizeof(char),d.length(),fp);
			fclose(fp);
			return true;
		}
	}
	return false;
}
	
void Debug(char* fmt,...)
{
	va_list p;
	va_start(p,fmt);

#ifdef _WIN32_WCE
	FILE* log;
	log = fopen(".\\Log.txt", "a+");
	if (log == NULL){
		return;
	}
	vfprintf(log, fmt,p);
	fclose(log);
#else
	char buf[10240];
	vsprintf(buf,fmt,p);
	if (strlen(buf)<=0) return ;
	printf(buf);
#endif
	va_end(p);
}

void Debug(TCHAR* fmt,...)
{
	va_list p;
	va_start(p,fmt);

#ifdef _WIN32_WCE
	FILE* log;
	log = fopen(".\\Log.txt", "a+");
	if (log == NULL){
		return;
	}
	vfwprintf(log, fmt,p);
	fclose(log);
#else
	TCHAR buf[10240];
	wvsprintf(buf,fmt,p);
	if (wcslen(buf)<=0) return ;
	wprintf(buf);
#endif
	va_end(p);
}

void INFO(char* f,...)
{
	int l = strlen(f)+512;
	AStr res;

	va_list ap;
	va_start(ap,f);

	while(1){
		res.buffer(l);
		res.length() = _vsnprintf( *res, res.alength(), f, ap );
		if (res.length()!=-1) break;
		l+=l;
	}
	va_end(ap);
	MessageBox(GetActiveWindow(),*CA2T(res),L"Info",MB_SETFOREGROUND);
}